/*
 * MageLordServletContext.java
 * Copyright 2012 Erik Strelzoff
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.magelord.servlet;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.magelord.utils.JSONUtil;
import javax.servlet.ServletContext;

public class MageLordServletContext {
	
	private final ServletContext m_servletContext;
	private final Gson m_gson;
	
	/** Creates a new instance of MageLordServletContext */
	public MageLordServletContext(ServletContext servletContext) {
		m_servletContext = servletContext;
		
		m_gson = JSONUtil.getGson();
	}
		
	// Construct a JSONObject to report an error to the client.
	public Object makeJSONError(String msg) {
		log(msg);
		return makeJSONError_internal(msg);
	}
	
	public Object makeJSONError(String msg, Throwable e) {
		log(msg, e);
		return makeJSONError_internal(msg);
	}
		
	private Object makeJSONError_internal(String msg) {
		//JSONObject jobj = new JSONObject();
		JsonObject jobj = new JsonObject();
		jobj.addProperty("Error", msg);
		return jobj;
	}
	
	public Gson getGson() {
		return m_gson;
	}
	
	public void log(String msg) {
		m_servletContext.log(getCallerString() + msg);
	}
	
	public void log(String msg, Throwable e) {
		m_servletContext.log(getCallerString() + msg, e);
	}
	
	private static String getCallerString() {
		StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
		
		// Go through the stack and find the first method which is not from us and
		// which is not from the java runtime (which can happen if we're being called
		// via System.out.	
		for (StackTraceElement traceElement : stackTrace) {
			String className = traceElement.getClassName();
			if ((!className.startsWith("com.magelord.servlet.MageLordServletContext")) &&
				(!className.startsWith("com.magelord.utils.Logger")) &&
				(!className.startsWith("java"))) {
				
				// If we were compiled without lines or source debug, then just
				// return null instead of something garbled.
				if ((traceElement.getFileName() == null) ||
					(traceElement.getLineNumber() == -1)) {
					return null;
				}

				StringBuilder sb = new StringBuilder(30);
				sb.append(traceElement.getFileName());
				sb.append(':');
				sb.append(traceElement.getLineNumber());
				
				// Pad to 30 characters to keep the log nice and neat
				while (sb.length() < 30) {
					sb.append('-');
				}
				sb.append(": ");
				return sb.toString();
			}
		}
		return null;
	}
}
